home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Software Vault: The Gold Collection
/
Software Vault - The Gold Collection (American Databankers) (1993).ISO
/
cdr25
/
me310.zip
/
UE310C.ZIP
/
MOUSE.C
< prev
next >
Wrap
Text File
|
1989-10-13
|
10KB
|
425 lines
/* MOUSE.C: Mouse functionality commands
for MicroEMACS 3.10
originally written by Dave G. Conroy
modified by Jeff Lomicka and Daniel Lawrence
*/
#include <stdio.h>
#include "estruct.h"
#include "etype.h"
#include "edef.h"
#include "elang.h"
#define MNONE 0 /* Mouse commands. */
#define MMOVE 1
#define MREG 2
#if MOUSE
NOSHARE int lastypos = HUGE; /* Last mouse event row. */
NOSHARE int lastxpos = HUGE; /* Last mouse event column. */
NOSHARE int lastmcmd = MNONE; /* Last mouse command. */
/*
* Move mouse button, down. The window that the
* mouse is in is always selected (this lets you select a
* window by clicking anyplace in it, even off the end
* of the text). If the mouse points at text then dot is
* moved to that location.
*/
PASCAL NEAR movemd(f, n)
{
register WINDOW *wp;
register WINDOW *lastwp;
register LINE *lp;
/* if anything has changed, reset the click count */
if (lastmcmd != MMOVE || lastypos!=ypos || lastxpos!=xpos)
nclicks = 0;
++nclicks;
lastwp = mousewindow(lastypos); /* remember last window */
/* reset the last position */
lastypos = ypos;
lastxpos = xpos;
lastmcmd = MMOVE;
/* if we move the mouse off the windows, don't move anything */
if ((wp=mousewindow(ypos)) == NULL)
return(FALSE);
/* if we are on the line with the point, adjust for extended lines */
if (wp == curwp && (lp = mouseline(wp, ypos)) == curwp->w_dotp)
xpos += lbound;
/* make the window the mouse points to current */
curwp = wp;
curbp = wp->w_bufp;
/* if we changed windows, update the modelines */
if (wp != lastwp)
upmode();
/* if we aren't off the end of the text, move the point to the mouse */
if ((lp=mouseline(wp, ypos)) != NULL) {
curwp->w_dotp = lp;
curwp->w_doto = mouseoffset(wp, lp, xpos);
}
return(TRUE);
}
/* mouse-region-down: mouse region operations
nclicks = 0: move cursor to mouse
set-mark
1: move cursor to mouse
kill-region
*/
PASCAL NEAR mregdown(f, n)
{
register WINDOW *wp;
register WINDOW *lastwp;
register LINE *lp;
/* if anything has changed, reset the click count */
if (lastmcmd != MREG || lastypos != ypos || lastxpos != xpos)
nclicks = 0;
++nclicks;
lastwp = mousewindow(lastypos); /* remember least window */
/* reset the last position */
lastypos = ypos;
lastxpos = xpos;
lastmcmd = MREG;
/* if we move the mouse off the windows, don't move anything */
if ((wp=mousewindow(ypos)) == NULL)
return(FALSE);
/* if we are on the line with the point, adjust for extended lines */
if (wp == curwp && (lp = mouseline(wp, ypos)) == curwp->w_dotp)
xpos += lbound;
/* make the window the mouse points to current */
curwp = wp;
curbp = wp->w_bufp;
/* if we changed windows, update the modelines */
if (wp != lastwp)
upmode();
/* if we aren't off the end of the text, move the point to the mouse */
if ((lp=mouseline(wp, ypos)) != NULL) {
curwp->w_dotp = lp;
curwp->w_doto = mouseoffset(wp, lp, xpos);
}
/* perform the region function */
if (nclicks == 1) {
return(setmark(FALSE, 0));
} else {
lastflag &= ~CFKILL;
return(killregion(FALSE, 0));
}
}
/* mouse-region-up: mouse region operations
If the corrosponding downclick was on a modeline, then we
wish to delete the indicated window. Otherwise we are using
this button to copy/paste.
nclicks = 0: move cursor to mouse
copy-region
1: move cursor to mouse
yank
3: reset nclicks to 0
*/
PASCAL NEAR mregup(f, n)
{
register WINDOW *wp;
register WINDOW *lastwp;
register LINE *lp;
register int lastmodeline; /* was the dowbclick on a modeline? */
/* if anything has changed, reset the click count */
if (lastmcmd != MREG || lastypos != ypos || lastxpos != xpos)
nclicks = 0;
++nclicks;
lastwp = mousewindow(lastypos); /* remember least window */
/* did we down click on a modeline? */
lastmodeline = ismodeline(lastwp, lastypos);
/* reset the last position */
lastypos = ypos;
lastxpos = xpos;
lastmcmd = MREG;
/* if we started on a modeline.... */
if (lastmodeline)
return(delwind(TRUE, 0));
/* if we move the mouse off the windows, don't move anything */
if ((wp=mousewindow(ypos)) == NULL)
return(FALSE);
/* if we are on the line with the point, adjust for extended lines */
if (wp == curwp && (lp = mouseline(wp, ypos)) == curwp->w_dotp)
xpos += lbound;
/* make the window the mouse points to current */
curwp = wp;
curbp = wp->w_bufp;
/* if we aren't off the end of the text, move the point to the mouse */
if ((lp=mouseline(wp, ypos)) != NULL && nclicks < 3) {
curwp->w_dotp = lp;
curwp->w_doto = mouseoffset(wp, lp, xpos);
}
/* if we changed windows, update the modelines, abort the new op */
if (wp != lastwp) {
upmode();
return(TRUE);
}
/* perform the region function */
if (nclicks == 1) {
return(copyregion(FALSE, 0));
} else if (nclicks == 2) {
return(yank(FALSE, 1));
} else {
nclicks = 0;
return(TRUE);
}
}
/*
* Move mouse button, up. The up click must be
* in the text region of a window. If the old click was in a
* mode line then the mode line moves to the row of the
* up click. If the old click is not in a mode line then the
* window scrolls. The code in this function is just
* too complex!
*/
PASCAL NEAR movemu(f, n)
{
register WINDOW *lastwp;
register WINDOW *wp;
register int lastmodeline; /* was the dowbclick on a modeline? */
register int deltay;
register int deltax;
/* no movement... fail the command */
if (lastypos==ypos && lastxpos==xpos)
return(FALSE);
/* if the down click was in the bottom right corner...
then we are resizing */
if (lastypos == term.t_nrow && lastxpos + 1 == term.t_ncol) {
(*term.t_eeop)();
newwidth(TRUE, xpos + 1);
newsize(TRUE, ypos + 1);
return(TRUE);
}
/* if the down click was not in a window.. fail the command
(for example, if we click on the command line) */
if ((lastwp=mousewindow(lastypos)) == NULL)
return(FALSE);
/* did we down click on a modeline? */
lastmodeline = ismodeline(lastwp, lastypos);
/* are we not in a window? fail it then */
if ((wp=mousewindow(ypos)) == NULL)
return(FALSE);
/* how far did we move? */
deltay = lastypos-ypos;
deltax = lastxpos-xpos;
lastypos = ypos;
lastxpos = xpos;
/* if we started on a modeline.... */
if (lastmodeline) {
/* move the window horizontally */
if (deltax != 0 && (diagflag || deltay == 0)) {
lastwp->w_fcol += deltax;
if (lastwp->w_fcol < 0)
lastwp->w_fcol = 0;
lastwp->w_flag |= WFMODE|WFHARD;
if (deltay == 0)
return(TRUE);
}
/* don't allow the bottom modeline to move */
if (lastwp->w_wndp == NULL)
return(FALSE);
/* shrink the current window */
if (deltay > 0) {
if (lastwp != wp)
return(FALSE);
curwp = wp;
curbp = wp->w_bufp;
return(shrinkwind(TRUE, deltay));
}
/* or grow it */
if (deltay < 0) {
if (wp != lastwp->w_wndp)
return(FALSE);
curwp = lastwp;
curbp = lastwp->w_bufp;
return(enlargewind(TRUE, -deltay));
}
}
/* did we up click in a modeline? fail it them */
if (ismodeline(wp, ypos) != FALSE)
return(FALSE);
/* we can not move outside the current window */
if (lastwp != wp)
return(FALSE);
/* move horizontally as well? */
if (deltax != 0 && (diagflag || deltay == 0)) {
wp->w_fcol += deltax;
if (wp->w_fcol < 0)
wp->w_fcol = 0;
wp->w_flag |= WFMODE;
}
/* and move the screen */
return(mvdnwind(TRUE, deltay));
}
/*
* Return a pointer to the WINDOW structure
* for the window in which "row" is located, or NULL
* if "row" isn't in any window. The mode line is
* considered to be part of the window.
*/
WINDOW *PASCAL NEAR mousewindow(row)
register int row;
{
register WINDOW *wp;
wp = wheadp;
while (wp != NULL) {
if (row < wp->w_ntrows+1)
return(wp);
row -= wp->w_ntrows+1;
wp = wp->w_wndp;
}
return(NULL);
}
/*
* The row "row" is a row within the window
* whose WINDOW structure is pointed to by the "wp"
* argument. Find the associated line, and return a pointer
* to it. Return NULL if the mouse is on the mode line,
* or if the mouse is pointed off the end of the
* text in the buffer.
*/
LINE *PASCAL NEAR mouseline(wp, row)
register WINDOW *wp;
register int row;
{
register LINE *lp;
row -= wp->w_toprow;
if (row >= wp->w_ntrows)
return(NULL);
lp = wp->w_linep;
while (row--) {
if (lp == wp->w_bufp->b_linep) /* Hit the end. */
return(NULL);
lp = lforw(lp);
}
return(lp);
}
/*
* Return the best character offset to use
* to describe column "col", as viewed from the line whose
* LINE structure is pointed to by "lp".
*/
PASCAL NEAR mouseoffset(wp, lp, col)
register WINDOW *wp;
register LINE *lp;
register int col;
{
register int c;
register int offset;
register int curcol;
register int newcol;
offset = 0;
curcol = 0;
col += wp->w_fcol; /* adjust for extended lines */
while (offset != llength(lp)) {
newcol = curcol;
if ((c=lgetc(lp, offset)) == '\t')
newcol += -(newcol % tabsize) + (tabsize - 1);
else if (c<32) /* ISCTRL */
++newcol;
++newcol;
if (newcol > col)
break;
curcol = newcol;
++offset;
}
return(offset);
}
PASCAL NEAR ismodeline(wp, row)
WINDOW *wp;
{
if (row == wp->w_toprow+wp->w_ntrows && modeflag)
return(TRUE);
return(FALSE);
}
/* The mouse has been used to resize the physical window. Now we need to
let emacs know about the newsize, and have him force a re-draw
*/
PASCAL NEAR resizm(f, n)
int f, n; /* these are ignored... we get the new size info from
the mouse driver */
{
(*term.t_eeop)();
newwidth(TRUE, xpos);
newsize(TRUE, ypos);
return(TRUE);
}
#else
mousehello()
{
}
#endif